/*
 * ml20gui - The MSN Webcam Recorder
 * This source code is under the GNU Public License (GPL).
 * Written by Ramiro Polla
 * Initial release: june 3rd, 2005
 *
 * this program records MSN Webcam Video
 */

#include "ml20gui.h"

typedef struct getversion_s
{
    HINSTANCE hInstance;
    HMODULE (__stdcall *GetModuleHandle)(LPCSTR);
    DWORD (__stdcall *GetModuleFileName)(HMODULE,LPSTR,DWORD);

    char szFileName[MAX_PATH];
} getversion_t;

static DWORD WINAPI getversionthread( getversion_t *ver )
{
    ver->hInstance = ver->GetModuleHandle(NULL);
    ver->GetModuleFileName(ver->hInstance, ver->szFileName, MAX_PATH);
    return TRUE;
}

static void dumb()
{
    ;
}

void *gvtaddress( )
{
    return (LPBYTE) getversionthread;
}

int gvtsize( )
{
    return (LPBYTE) dumb - (LPBYTE) getversionthread;
}

char *get_pid_filename( int pid )
{
    HINSTANCE hkernel;
    HANDLE remotethread;
    HANDLE remoteproc;
    void* remotecode;
    void* remotedata;
    getversion_t ver;
    char* chuchu;

    hkernel = GetModuleHandle( "kernel32" );
    ver.GetModuleHandle = (HMODULE (__stdcall *)(LPCSTR)) GetProcAddress( hkernel, "GetModuleHandleA" );
    ver.GetModuleFileName = (DWORD (__stdcall *)(HMODULE,LPSTR,DWORD)) GetProcAddress( hkernel, "GetModuleFileNameA" );

    remoteproc = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid );

    remotecode = VirtualAllocEx( remoteproc, 0, gvtsize(), MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    WriteProcessMemory( remoteproc, remotecode, gvtaddress(), gvtsize(), NULL );

    remotedata = VirtualAllocEx( remoteproc, 0, sizeof(ver), MEM_COMMIT, PAGE_READWRITE );
    WriteProcessMemory( remoteproc, remotedata, &ver, sizeof(ver), NULL );

    remotethread = CreateRemoteThread( remoteproc, 0, 0, (LPTHREAD_START_ROUTINE) remotecode, remotedata, 0, NULL );
    WaitForSingleObject( remotethread, INFINITE );

    ReadProcessMemory( remoteproc, remotedata, &ver, sizeof(ver), NULL );
    VirtualFreeEx( remoteproc, remotecode, 0, MEM_RELEASE );
    VirtualFreeEx( remoteproc, remotedata, 0, MEM_RELEASE );

    CloseHandle( remoteproc );

    chuchu = malloc( MAX_PATH );
    strcpy( chuchu, ver.szFileName );
    return chuchu;
}
